﻿Imports System
Imports System.Collections.Generic
Imports System.Globalization
Imports System.Reflection
Imports System.Runtime.InteropServices
Imports System.Xml

Namespace System.Workflow.ComponentModel.Serialization
    Friend NotInheritable Class ExtendedPropertyInfo
        Inherits PropertyInfo
        ' Methods
        Friend Sub New(ByVal propertyInfo As PropertyInfo, ByVal getValueHandler As GetValueHandler, ByVal setValueHandler As SetValueHandler, ByVal qualifiedNameHandler As GetQualifiedNameHandler)
            Me.realPropertyInfo = propertyInfo
            Me.OnGetValue = getValueHandler
            Me.OnSetValue = setValueHandler
            Me.OnGetXmlQualifiedName = qualifiedNameHandler
        End Sub

        Friend Sub New(ByVal propertyInfo As PropertyInfo, ByVal getValueHandler As GetValueHandler, ByVal setValueHandler As SetValueHandler, ByVal qualifiedNameHandler As GetQualifiedNameHandler, ByVal manager As WorkflowMarkupSerializationManager)
            Me.New(propertyInfo, getValueHandler, setValueHandler, qualifiedNameHandler)
            Me.manager = manager
        End Sub

        Public Overrides Function GetAccessors(ByVal nonPublic As Boolean) As MethodInfo()
            Return Me.realPropertyInfo.GetAccessors(nonPublic)
        End Function

        Public Overrides Function GetCustomAttributes(ByVal inherit As Boolean) As Object()
            Return Me.realPropertyInfo.GetCustomAttributes(inherit)
        End Function

        Public Overrides Function GetCustomAttributes(ByVal attributeType As Type, ByVal inherit As Boolean) As Object()
            Return Me.realPropertyInfo.GetCustomAttributes(attributeType, inherit)
        End Function

        Public Overrides Function GetGetMethod(ByVal nonPublic As Boolean) As MethodInfo
            Return Me.realPropertyInfo.GetGetMethod(nonPublic)
        End Function

        Public Overrides Function GetIndexParameters() As ParameterInfo()
            Return Me.realPropertyInfo.GetIndexParameters
        End Function

        Public Overrides Function GetSetMethod(ByVal nonPublic As Boolean) As MethodInfo
            Return Me.realPropertyInfo.GetSetMethod(nonPublic)
        End Function

        Public Overrides Function GetValue(ByVal obj As Object, ByVal invokeAttr As BindingFlags, ByVal binder As Binder, ByVal index As Object(), ByVal culture As CultureInfo) As Object
            If (Not Me.OnGetValue Is Nothing) Then
                Return Me.OnGetValue.Invoke(Me, obj)
            End If
            Return Nothing
        End Function

        Public Function GetXmlQualifiedName(ByVal manager As WorkflowMarkupSerializationManager, <Out> ByRef prefix As String) As XmlQualifiedName
            prefix = String.Empty
            If (Not Me.OnGetXmlQualifiedName Is Nothing) Then
                Return Me.OnGetXmlQualifiedName.Invoke(Me, manager, prefix)
            End If
            Return Nothing
        End Function

        Public Overrides Function IsDefined(ByVal attributeType As Type, ByVal inherit As Boolean) As Boolean
            Return Me.realPropertyInfo.IsDefined(attributeType, inherit)
        End Function

        Friend Shared Function IsExtendedProperty(ByVal manager As WorkflowMarkupSerializationManager, ByVal xmlQualifiedName As XmlQualifiedName) As Boolean
            Dim current As Object = manager.Context.Current
            If (Not current Is Nothing) Then
                Dim info As ExtendedPropertyInfo
                For Each info In manager.GetExtendedProperties(current)
                    Dim prefix As String = String.Empty
                    Dim name As XmlQualifiedName = info.GetXmlQualifiedName(manager, prefix)
                    If (name.Name.Equals(xmlQualifiedName.Name, StringComparison.Ordinal) AndAlso name.Namespace.Equals(xmlQualifiedName.Namespace, StringComparison.Ordinal)) Then
                        Return True
                    End If
                Next
            End If
            Return False
        End Function

        Friend Shared Function IsExtendedProperty(ByVal manager As WorkflowMarkupSerializationManager, ByVal propInfos As IList([Of] PropertyInfo), ByVal xmlQualifiedName As XmlQualifiedName) As Boolean
            Dim info As PropertyInfo
            For Each info In propInfos
                Dim info2 As ExtendedPropertyInfo = [TryCast](info,ExtendedPropertyInfo)
                If (Not info2 Is Nothing) Then
                    Dim prefix As String = String.Empty
                    Dim name As XmlQualifiedName = info2.GetXmlQualifiedName(manager, prefix)
                    If (name.Name.Equals(xmlQualifiedName.Name, StringComparison.Ordinal) AndAlso name.Namespace.Equals(xmlQualifiedName.Namespace, StringComparison.Ordinal)) Then
                        Return True
                    End If
                End If
            Next
            Return False
        End Function

        Public Overrides Sub SetValue(ByVal obj As Object, ByVal value As Object, ByVal invokeAttr As BindingFlags, ByVal binder As Binder, ByVal index As Object(), ByVal culture As CultureInfo)
            If (Not Me.OnSetValue Is Nothing) Then
                Me.OnSetValue.Invoke(Me, obj, value)
            End If
        End Sub


        ' Properties
        Public Overrides ReadOnly Property Attributes As PropertyAttributes
            Get
                Return Me.realPropertyInfo.Attributes
            End Get
        End Property

        Public Overrides ReadOnly Property CanRead As Boolean
            Get
                Return Me.realPropertyInfo.CanRead
            End Get
        End Property

        Public Overrides ReadOnly Property CanWrite As Boolean
            Get
                Return Me.realPropertyInfo.CanWrite
            End Get
        End Property

        Public Overrides ReadOnly Property DeclaringType As Type
            Get
                Return Me.realPropertyInfo.DeclaringType
            End Get
        End Property

        Public Overrides ReadOnly Property Name As String
            Get
                Return Me.realPropertyInfo.Name
            End Get
        End Property

        Public Overrides ReadOnly Property PropertyType As Type
            Get
                Return Me.realPropertyInfo.PropertyType
            End Get
        End Property

        Friend ReadOnly Property RealPropertyInfo As PropertyInfo
            Get
                Return Me.realPropertyInfo
            End Get
        End Property

        Public Overrides ReadOnly Property ReflectedType As Type
            Get
                Return Me.realPropertyInfo.ReflectedType
            End Get
        End Property

        Friend ReadOnly Property SerializationManager As WorkflowMarkupSerializationManager
            Get
                Return Me.manager
            End Get
        End Property


        ' Fields
        Private manager As WorkflowMarkupSerializationManager
        Private OnGetValue As GetValueHandler
        Private OnGetXmlQualifiedName As GetQualifiedNameHandler
        Private OnSetValue As SetValueHandler
        Private realPropertyInfo As PropertyInfo
    End Class
End Namespace

